home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
WASTE 1.2
/
WASTE Demo ƒ
/
WEDemoScripting.c
< prev
next >
Wrap
Text File
|
1996-05-19
|
9KB
|
339 lines
/*
WASTE Demo Project:
Minimal Scripting Support:
service "get data" and "set data" events
in which the object descriptor is "contents of selection"
Based on public domain code written by:
Ed Lai, Apple Computer Inc.
Copyright © 1993-1996 Marco Piovanelli
All Rights Reserved
*/
#ifndef __AEOBJECTS__
#include <AEObjects.h>
#endif
#ifndef __AEREGISTRY__
#include <AERegistry.h>
#endif
#ifndef __WEDEMOAPP__
#include "WEDemoIntf.h"
#endif
enum {
kMaxPropLevel = 2
};
typedef DescType PropArray[kMaxPropLevel];
static void InitDesc(AEDesc *desc)
{
desc->descriptorType = typeNull;
desc->dataHandle = nil;
}
static Boolean PropertyOf(const AERecord *spec, short *propLevel, PropArray properties)
{
AERecord objSpec;
AEKeyword key;
DescType theType;
DescType actualType;
Size actualSize;
Boolean retVal = false;
InitDesc(&objSpec);
// if spec is an Apple event (*propLevel = 0), extract its direct parameter
// otherwise spec is an object specifier record: extract its container param
key = (*propLevel == 0) ? keyDirectObject : keyAEContainer;
// extract object specifier
if (AEGetParamDesc(spec, key, typeAERecord, &objSpec) != noErr)
goto cleanup;
// does this object specifier specify a property?
if (AEGetParamPtr(&objSpec, keyAEDesiredClass, typeType, &actualType,
&theType, sizeof(theType), &actualSize) != noErr)
goto cleanup;
// sanity check: make sure the key form is formPropertyID
// this is probably redundant, but checking doesn't hurt
if (AEGetParamPtr(&objSpec, keyAEKeyForm, typeEnumerated, &actualType,
&theType, sizeof(theType), &actualSize) != noErr)
goto cleanup;
if (theType != formPropertyID)
goto cleanup;
// which property does this object specifier specify?
if (AEGetParamPtr(&objSpec, keyAEKeyData, typeType, &actualType,
&theType, sizeof(theType), &actualSize) != noErr)
goto cleanup;
// bump property level and save property tag into property array
properties[(*propLevel)++] = theType;
// property of what?
if (AESizeOfParam(&objSpec, keyAEContainer, &actualType, &actualSize) == noErr)
if (actualType == typeNull)
// property of application (i.e., null container): we are done
retVal = true;
else if ((actualType == typeObjectSpecifier) && (*propLevel < kMaxPropLevel))
// property of another object, so do a recursive call
// unless we have already reached max recursion depth
retVal = PropertyOf(&objSpec, propLevel, properties);
cleanup:
AEDisposeDesc(&objSpec);
return retVal;
}
OSErr WEGetContentsDesc(long rangeStart, long rangeEnd, Boolean wantStyledText,
AEDesc *desc, WEReference we)
{
AEDesc textDesc, stylesDesc, recordDesc;
OSErr err;
InitDesc(desc);
InitDesc(&textDesc);
InitDesc(&stylesDesc);
InitDesc(&recordDesc);
// allocate a handle to hold the text
textDesc.dataHandle = NewHandle(0);
textDesc.descriptorType = typeChar;
if ((err = MemError()) != noErr)
goto cleanup;
if (wantStyledText)
{
// allocate a handle to hold the styles
stylesDesc.dataHandle = NewHandle(0);
stylesDesc.descriptorType = typeScrapStyles;
if ((err = MemError()) != noErr)
goto cleanup;
} // if wantStyledText
// make a copy of the specified text range
if ((err = WECopyRange(rangeStart, rangeEnd, textDesc.dataHandle,
(StScrpHandle) stylesDesc.dataHandle, nil, we)) != noErr)
goto cleanup;
if (wantStyledText)
{
// create an Apple event record to hold text + styles
if ((err = AECreateList(nil, 0, true, &recordDesc)) != noErr)
goto cleanup;
// add the text descriptor to the record
if ((err = AEPutParamDesc(&recordDesc, keyAEText, &textDesc)) != noErr)
goto cleanup;
AEDisposeDesc(&textDesc);
// add the styles descriptor to the record
if ((err = AEPutParamDesc(&recordDesc, keyAEStyles, &stylesDesc)) != noErr)
goto cleanup;
AEDisposeDesc(&stylesDesc);
// coerce the record into a styled text descriptor
if ((err = AECoerceDesc(&recordDesc, typeStyledText, desc)) != noErr)
goto cleanup;
}
else {
*desc = textDesc;
InitDesc(&textDesc);
}
err = noErr;
cleanup:
AEDisposeDesc(&textDesc);
AEDisposeDesc(&stylesDesc);
AEDisposeDesc(&recordDesc);
return err;
}
OSErr WESetContentsDesc(long rangeStart, long rangeEnd,
const AEDesc *desc, WEReference we)
{
AEDesc textDesc, stylesDesc, recordDesc;
OSErr err;
InitDesc(&textDesc);
InitDesc(&stylesDesc);
InitDesc(&recordDesc);
// we expect desc type to be either TEXT or STXT
if (desc->descriptorType == typeStyledText)
{
// STYLED TEXT
// coerce the styled text descriptor to an Apple event record
if ((err = AECoerceDesc(desc, typeAERecord, &recordDesc)) != noErr)
goto cleanup;
// extract text + styles from the record
if ((err = AEGetParamDesc(&recordDesc, keyAEText, typeChar, &textDesc)) != noErr)
goto cleanup;
if ((err = AEGetParamDesc(&recordDesc, keyAEStyles, typeScrapStyles, &stylesDesc)) != noErr)
goto cleanup;
}
else {
// UNSTYLED TEXT
if ((err = AECoerceDesc(desc, typeChar, &textDesc)) != noErr)
goto cleanup;
}
// replace the specified range with the given text
HLock(textDesc.dataHandle);
WESetSelection(rangeStart, rangeEnd, we);
err = WEInsert(*textDesc.dataHandle, GetHandleSize(textDesc.dataHandle),
(StScrpHandle) stylesDesc.dataHandle, nil, we);
HUnlock(textDesc.dataHandle);
cleanup:
AEDisposeDesc(&recordDesc);
AEDisposeDesc(&textDesc);
AEDisposeDesc(&stylesDesc);
return err;
}
static pascal OSErr HandleGetData(const AppleEvent *ae, AppleEvent *reply, long refCon)
{
#pragma unused (refCon)
AEDesc textDesc;
DocumentHandle hDocument;
short propLevel = 0;
PropArray properties;
FlavorType requestedType;
Boolean wantStyledText = false;
DescType actualType;
Size actualSize;
long selStart, selEnd;
OSErr err;
InitDesc(&textDesc);
// the only Apple event object we recognize is "contents of selection"
err = errAENoSuchObject;
if (!PropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
(properties[0] != pContents) || (properties[1] != pSelection))
{
goto cleanup;
}
// extract the optional parameter keyAERequestedType, if present
// The Apple Event Registry says this parameter can be a list
// of type tags, but in most cases it is just a single tag, as we assume here.
if (AEGetParamPtr(ae, keyAERequestedType, typeType, &actualType,
&requestedType, sizeof(requestedType), &actualSize) == noErr)
{
wantStyledText = (requestedType == typeStyledText);
}
// make sure there is a document window in front
err = errAENoUserSelection;
if ((hDocument = GetWindowDocument(FrontWindow())) == nil)
{
goto cleanup;
}
// get the selection range
WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
// create an Apple event descriptor for the selected text
if ((err = WEGetContentsDesc(selStart, selEnd, wantStyledText,
&textDesc, (*hDocument)->we)) != noErr)
{
goto cleanup;
}
// put the text descriptor into the reply event
if ((err = AEPutParamDesc(reply, keyDirectObject, &textDesc)) != noErr)
{
goto cleanup;
}
// clear result code
err = noErr;
cleanup:
AEDisposeDesc(&textDesc);
return err;
}
static pascal OSErr HandleSetData(const AppleEvent *ae, AppleEvent *reply, long refCon)
{
#pragma unused (reply, refCon)
AEDesc textDesc;
DocumentHandle hDocument;
short propLevel = 0;
PropArray properties;
long selStart, selEnd;
OSErr err;
InitDesc(&textDesc);
// the only Apple event object we recognize is "contents of selection"
err = errAENoSuchObject;
if (!PropertyOf(ae, &propLevel, properties) || (propLevel != 2) ||
(properties[0] != pContents) || (properties[1] != pSelection))
{
goto cleanup;
}
// make sure there is a document window in front
err = errAENoUserSelection;
if ((hDocument = GetWindowDocument(FrontWindow())) == nil)
{
goto cleanup;
}
// extract the required keyAEData parameter
if ((err = AEGetParamDesc(ae, keyAEData, typeWildCard, &textDesc)) != noErr)
goto cleanup;
// get current selection range
WEGetSelection(&selStart, &selEnd, (*hDocument)->we);
// set the contents of the selection
if ((err = WESetContentsDesc(selStart, selEnd, &textDesc, (*hDocument)->we)) != noErr)
{
goto cleanup;
}
// clear result code
err = noErr;
cleanup:
AEDisposeDesc(&textDesc);
return err;
}
OSErr InstallCoreHandlers(void)
{
OSErr err;
if ((err = AEInstallEventHandler(kAECoreSuite, kAEGetData,
NewAEEventHandlerProc(HandleGetData), 0L, false)) != noErr)
{
return err;
}
if ((err = AEInstallEventHandler(kAECoreSuite, kAESetData,
NewAEEventHandlerProc(HandleSetData), 0L, false)) != noErr)
{
return err;
}
return noErr;
}